package org.teachertools.web.controller;

import java.util.LinkedList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.teachertools.data.Eleve;
import org.teachertools.services.EleveService;
import org.teachertools.services.exception.ServiceException;
import org.teachertools.web.validator.EleveValidator;

@Controller
@RequestMapping(value = { "/eleves/*" })
public class EleveController {

    private static final Logger logger = Logger.getLogger(EleveController.class);

    @Resource
    private EleveService eleveService;

    @RequestMapping(value = { "show" })
    public String searchEleves(ModelMap model, @ModelAttribute Eleve eleve) throws ServiceException {
        logger.debug("method searchEleves called in the controller");
        List<Eleve> eleves = this.eleveService.searchByExample(eleve);
        if (logger.isDebugEnabled()) {
            logger.debug("Found " + eleves.size() + " students");
        }
        model.addAttribute("eleves", eleves);
        return "eleves/show";
    }

    @RequestMapping(value = { "ajax/show" })
    public String ajaxSearchEleves(ModelMap model, @ModelAttribute Eleve eleve) throws ServiceException {
        logger.debug("Ajax Invocation of searchEleves");
        searchEleves(model, eleve);
        return "eleves/results";
    }

    @RequestMapping(value = "add", method = RequestMethod.GET)
    public String prepareAddEleve(ModelMap model) throws ServiceException {
        logger.debug("method prepareAddEleve called in the controller");
        model.addAttribute("eleve", new Eleve());
        return "eleves/view";
    }

    @RequestMapping(value = "add", method = RequestMethod.POST)
    public String addEleve(ModelMap model, @ModelAttribute Eleve eleve, BindingResult result) throws ServiceException {
        logger.debug("method addEleve called in the controller");
        new EleveValidator().validate(eleve, result);
        if (result.hasErrors()) {
            logger.debug("Validation has errors, no action");
            return "eleves/view";
        } else {
            this.eleveService.save(eleve);
        }
        LinkedList<String> messages = new LinkedList<String>();
        messages.add("success.save");
        model.addAttribute("messages", messages);
        return searchEleves(model, new Eleve());// getEleves(model);
    }

    @RequestMapping(value = "view/{id}", method = RequestMethod.GET)
    public String viewEleve(ModelMap model, @PathVariable("id") long eleveId) throws ServiceException {
        logger.debug("method viewEleve called in the controller");
        model.addAttribute("eleve", this.eleveService.get(eleveId));
        return "eleves/view";
    }

    @RequestMapping(value = "update", method = RequestMethod.POST)
    public String updateEleve(ModelMap model, @ModelAttribute Eleve eleve, BindingResult result)
            throws ServiceException {
        logger.debug("method updateEleve called in the controller");
        new EleveValidator().validate(eleve, result);
        Eleve loadedEleve = this.eleveService.get(eleve.getId());
        eleve.setNotes(loadedEleve.getNotes());
        this.eleveService.update(eleve);

        LinkedList<String> messages = new LinkedList<String>();
        messages.add("success.save");
        model.addAttribute("messages", messages);
        return viewEleve(model, eleve.getId());
    }

    @RequestMapping(value = "delete/{id}", method = RequestMethod.GET)
    public String deleteEleve(ModelMap model, @PathVariable("id") long eleveId) throws ServiceException {
        logger.debug("method deleteEleve called in the controller");
        this.eleveService.deleteById(eleveId);
        return searchEleves(model, new Eleve());// getEleves(model);
    }
}
